//
// Created by wxd on 2025/8/10.
//

#pragma once


#ifndef SPHERE_H
#define SPHERE_H

#include "BaseGeometry.h"
#include "glm/glm.hpp"
#include "../application/app/Application.h"

class Sphere : public BaseGeometry{
public:
    Sphere() : m_Radius(0.f), m_Center(glm::vec3(0.f)), m_Color(glm::vec3(0.f)) {
        m_DrawMode = GL_TRIANGLES;
        m_GeometryType = GeometryType::TRIANGLE;
        if (EngineApp.isGLInited()) {
            BaseGeometry::initVAO();
        }
    }

    Sphere(const DrawType type, const GLenum mode) : m_Radius(0.f), m_Center(glm::vec3(0.f)), m_Color(glm::vec3(0.f)) {
        m_DrawType = type;
        m_DrawMode = mode;
        m_GeometryType = GeometryType::TRIANGLE;
        if (EngineApp.isGLInited()) {
            BaseGeometry::initVAO();
        }
    }

    Sphere(const float radius, const glm::vec3& center, const glm::vec3& color) : m_Radius(radius), m_Center(center), m_Color(color) {
        m_DrawMode = GL_TRIANGLES;
        m_DrawType = DrawType::DRAW_ELEMENTS;
        m_GeometryType = GeometryType::TRIANGLE;
        m_RasterLatitudes = 60;
        m_RasterLongitudes = 60;
        if (EngineApp.isGLInited()) {
            BaseGeometry::initVAO();
            raster();
        }
    }

    Sphere(const DrawType type, const GLenum mode, const float radius, const glm::vec3& center, const glm::vec3& color) :
    m_Radius(radius), m_Center(center), m_Color(color) {
        m_DrawType = type;
        m_DrawMode = mode;
        m_GeometryType = GeometryType::TRIANGLE;
        m_RasterLatitudes = 60;
        m_RasterLongitudes = 60;
        if (EngineApp.isGLInited()) {
            BaseGeometry::initVAO();
            raster();
        }
    }

    Sphere(const DrawType type, const GLenum mode, const float radius,
           const glm::vec3& center, const glm::vec3& color,
           const unsigned int latitudes, const unsigned int longitudes) : m_Radius(radius), m_Center(center), m_Color(color) {
        m_DrawType = type;
        m_DrawMode = mode;
        m_GeometryType = GeometryType::TRIANGLE;
        m_RasterLatitudes = latitudes;
        m_RasterLongitudes = longitudes;
        if (EngineApp.isGLInited()) {
            BaseGeometry::initVAO();
            raster();
        }
    }

    std::unique_ptr<BaseGeometry> clone() const override {
        return std::make_unique<Sphere>(*this);
    }

    void setRadius(float radius);
    void setCenter(glm::vec3 center);
    void setColor(glm::vec3 color);
    void setRasterLatitudes(unsigned int latitudes);
    void setRasterLongitudes(unsigned int longitudes);

    glm::vec3 getCenter() const;
    float getRadius() const;
    glm::vec3 getColor() const;

    unsigned int getGridFaces() const;
    unsigned int getGirdVertices() const;

    void raster();

private:

    float m_Radius;
    glm::vec3 m_Center;
    glm::vec3 m_Color;
    unsigned int m_RasterLatitudes;     // 纬线：水平
    unsigned int m_RasterLongitudes;    // 经线：竖直

    unsigned int m_GridFaces;           // mesh之后的球体对应的网格面数
    unsigned int m_GridVertices;        // mesh之后的球体对应的网格顶点数

    std::vector<glm::vec3> m_SphereVertices;
    std::vector<glm::vec2> m_SphereTexCoords;
    std::vector<glm::vec3> m_SphereNormals;
    std::vector<glm::uvec3> m_SphereFaces;
};



#endif //SPHERE_H
